import axios, { AxiosResponse, AxiosError } from 'axios';
import { HttpError, ResponseData, RequestConfig } from './types';
import { 
  enableRequestLog, 
  enableResponseLog, 
  defaultRetryCount, 
  defaultRetryDelay 
} from './config';

// 创建 HTTP 错误对象
export function createHttpError(
  message: string,
  code: string | number = 'UNKNOWN',
  originalError?: any,
  config?: RequestConfig,
  response?: AxiosResponse
): HttpError {
  const error: HttpError = new Error(message) as HttpError;
  error.name = 'HttpError';
  error.code = code;
  error.originalError = originalError;
  error.config = config;
  error.response = response;
  return error;
}

// 处理 HTTP 状态码
export function handleHttpStatusError(error: AxiosError): HttpError {
  const { response, config } = error;
  let message = '未知错误';
  let code = 'UNKNOWN';

  if (response) {
    const { status } = response;
    code = status.toString();

    switch (status) {
      case 400:
        message = '请求错误';
        break;
      case 401:
        message = '未授权，请重新登录';
        break;
      case 403:
        message = '拒绝访问';
        break;
      case 404:
        message = '请求地址出错';
        break;
      case 408:
        message = '请求超时';
        break;
      case 500:
        message = '服务器内部错误';
        break;
      case 501:
        message = '服务未实现';
        break;
      case 502:
        message = '网关错误';
        break;
      case 503:
        message = '服务不可用';
        break;
      case 504:
        message = '网关超时';
        break;
      default:
        message = `请求失败 (${status})`;
    }
  } else if (error.message && error.message.includes('timeout')) {
    message = '请求超时';
    code = 'TIMEOUT';
  } else if (error.message && error.message.includes('Network Error')) {
    message = '网络错误，请检查您的网络连接';
    code = 'NETWORK_ERROR';
  }

  return createHttpError(message, code, error, config as RequestConfig, response as AxiosResponse);
}

// 处理响应数据
export function handleResponseData<T>(response: AxiosResponse<ResponseData<T>>): T {
  const res = response.data;

  // 如果后端设置了统一的状态码，可以在这里处理
  if (res.code !== 200 && res.code !== 0) {
    const error = createHttpError(
      res.message || '请求失败',
      res.code,
      res,
      response.config as RequestConfig,
      response
    );
    return Promise.reject(error);
  }

  return res.data;
}

// 日志辅助函数
export function printRequestLog(config: RequestConfig): void {
  if (enableRequestLog) {
    console.log(
      `%c 请求: ${config.method?.toUpperCase()} ${config.url} %c`,
      'background: #2d8cf0; color: #fff; border-radius: 3px 0 0 3px; padding: 1px;',
      'background: #5cadff; color: #fff; border-radius: 0 3px 3px 0; padding: 1px;',
      config
    );
  }
}

export function printResponseLog(response: AxiosResponse): void {
  if (enableResponseLog) {
    console.log(
      `%c 响应: ${response.config.method?.toUpperCase()} ${response.config.url} %c`,
      'background: #19be6b; color: #fff; border-radius: 3px 0 0 3px; padding: 1px;',
      'background: #47cb89; color: #fff; border-radius: 0 3px 3px 0; padding: 1px;',
      response
    );
  }
}

export function printErrorLog(error: HttpError): void {
  console.error(
    `%c 错误: ${error.config?.method?.toUpperCase()} ${error.config?.url} %c`,
    'background: #ed4014; color: #fff; border-radius: 3px 0 0 3px; padding: 1px;',
    'background: #ff7875; color: #fff; border-radius: 0 3px 3px 0; padding: 1px;',
    error
  );
}

// 请求重试函数
export function retry(config: RequestConfig, error: AxiosError) {
  const retryConfig = config;
  const retryCount = retryConfig.retryCount || defaultRetryCount;
  const retryDelay = retryConfig.retryDelay || defaultRetryDelay;
  
  // 设置当前重试次数
  if (!retryConfig.headers) {
    retryConfig.headers = {};
  }
  const currentRetryCount = parseInt(retryConfig.headers['x-retry-count'] as string || '0');
  
  // 如果当前重试次数超过最大重试次数，则抛出错误
  if (currentRetryCount >= retryCount) {
    return Promise.reject(error);
  }
  
  // 增加重试次数
  retryConfig.headers['x-retry-count'] = (currentRetryCount + 1).toString();
  
  // 延迟重试
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(axios(retryConfig));
    }, retryDelay);
  });
}

// 创建取消令牌
export function createCancelToken(cancelTokenId?: string) {
  if (!cancelTokenId) {
    return undefined;
  }
  
  // 在存储中查找令牌
  const controller = new AbortController();
  
  // 存储取消函数
  window.__HTTP_CANCEL_TOKENS__ = window.__HTTP_CANCEL_TOKENS__ || {};
  window.__HTTP_CANCEL_TOKENS__[cancelTokenId] = controller;
  
  return controller.signal;
}

// 取消请求
export function cancelRequest(cancelTokenId: string) {
  if (!cancelTokenId || !window.__HTTP_CANCEL_TOKENS__) {
    return false;
  }
  
  const controller = window.__HTTP_CANCEL_TOKENS__[cancelTokenId];
  if (controller) {
    controller.abort();
    delete window.__HTTP_CANCEL_TOKENS__[cancelTokenId];
    return true;
  }
  
  return false;
}

// 扩展 Window 接口
declare global {
  interface Window {
    __HTTP_CANCEL_TOKENS__?: Record<string, AbortController>;
  }
} 